﻿namespace Forms
{
    using Microsoft.Office.Interop.Excel;
    using Microsoft.VisualBasic;
    using Microsoft.VisualBasic.CompilerServices;
    using Microsoft.VisualBasic.FileIO;

    using System;
    using System.Collections;
    using System.Data;
    using System.IO;
    using System.Reflection;
    using System.Security.Permissions;
    using System.Text;

    public class DataFile
    {
        private string[] arCSV_Extensions;
        private string[] arXLS_Extensions;
        public System.Data.DataTable Data;
        private int varColLimit;
        private string varCsvDelimiter;
        private Encoding varCsvEncoding;
        private int varDetectionLimit;
        private bool varDoDetect;
        private bool varExplicitDetect;
        private string varExtension;
        private string varFileName;
        private dfFileType varFileType;
        private string[] varHeaderDetect;
        private TimeSpan varReadingTime;
        private int varRowLimit;
        private DateTime varStartDate;
        private string varStrippedChars;
        private int varXlsWorksheet;

        public DataFile()
        {
            this.Data = new System.Data.DataTable();
            this.arCSV_Extensions = new string[] { ".CSV", ".TXT" };
            this.arXLS_Extensions = new string[] { ".XLS", ".XLSX", ".XLSM" };
            this.varStrippedChars = ".,!$%&/\\()=?[]^-_:'#+*~`\x00b4@\"";
            this.varDoDetect = false;
            this.varExplicitDetect = true;
            this.varDetectionLimit = 0;
            this.varCsvDelimiter = ";";
            this.varCsvEncoding = Encoding.Default;
            this.varXlsWorksheet = 1;
            this.varColLimit = 100;
            this.varRowLimit = 0;
        }

        public DataFile(string FileName)
        {
            this.Data = new System.Data.DataTable();
            this.arCSV_Extensions = new string[] { ".CSV", ".TXT" };
            this.arXLS_Extensions = new string[] { ".XLS", ".XLSX", ".XLSM" };
            this.varStrippedChars = ".,!$%&/\\()=?[]^-_:'#+*~`\x00b4@\"";
            this.varDoDetect = false;
            this.varExplicitDetect = true;
            this.varDetectionLimit = 0;
            this.varCsvDelimiter = ";";
            this.varCsvEncoding = Encoding.Default;
            this.varXlsWorksheet = 1;
            this.varColLimit = 100;
            this.varRowLimit = 0;
            this.FileName = FileName;
        }

        private bool CompareFields(string Feld, string Needle)
        {
            bool flag = false;
            if (this.varExplicitDetect)
            {
                if (Feld == Needle)
                {
                    flag = true;
                }
                return flag;
            }
            Feld = this.StripChars(Feld.ToUpper(), this.varStrippedChars);
            Needle = this.StripChars(Needle.ToUpper(), this.varStrippedChars);
            if (Feld.Contains(Needle))
            {
                flag = true;
            }
            return flag;
        }

        private void EndTimer()
        {
            this.varReadingTime = this.varStartDate.Subtract(DateAndTime.Now);
        }

        private void GetTypeFromExtension()
        {
            foreach (string str in this.arCSV_Extensions)
            {
                if (this.varExtension.ToUpper() == str)
                {
                    this.varFileType = dfFileType.CSV;
                    return;
                }
            }
            foreach (string str2 in this.arXLS_Extensions)
            {
                if (this.varExtension.ToUpper() == str2)
                {
                    this.varFileType = dfFileType.XLS;
                    return;
                }
            }
            this.varFileType = dfFileType.Unknown;
        }

        public void Read()
        {
            this.Data.Clear();
            this.StartTimer();
            switch (this.FileType)
            {
                case dfFileType.Unknown:
                    throw new dfUnknownFileTypeException(this.FileName, true);

                case dfFileType.CSV:
                    this.ReadCSV();
                    break;

                case dfFileType.XLS:
                    this.ReadXLS();
                    break;
            }
            this.EndTimer();
        }

        private void ReadCSV()
        {
            using (TextFieldParser parser = new TextFieldParser(this.varFileName, this.varCsvEncoding))
            {
                string[] strArray3 = new string[]{};
                parser.TextFieldType = FieldType.Delimited;
                parser.SetDelimiters(new string[] { this.varCsvDelimiter });
                bool flag = false;
                string[] strArray2 = new string[this.varColLimit + 1];
                if (this.varDoDetect)
                {
                    strArray3 = new string[(this.varHeaderDetect.Length - 1) + 1];
                }
                int num3 = 0;
                while (!parser.EndOfData)
                {
                    DataColumn column;
                    string[] strArray = parser.ReadFields();
                    if (!this.varDoDetect & !flag)
                    {
                        int varColLimit = this.varColLimit;
                        for (int i = 0; i <= varColLimit; i++)
                        {
                            column = this.Data.Columns.Add(Conversions.ToString(i), typeof(string));
                            strArray2[i] = Conversions.ToString(i);
                        }
                        flag = true;
                    }
                    if (flag)
                    {
                        DataRow row = this.Data.NewRow();
                        int index = 0;
                        foreach (string str in strArray)
                        {
                            if (strArray2[index] != null)
                            {
                                row[strArray2[index]] = str;
                            }
                            index++;
                        }
                        this.Data.Rows.Add(row);
                    }
                    if (this.varDoDetect & !flag)
                    {
                        foreach (string str2 in strArray)
                        {
                            int num2 = 0;
                            foreach (string str3 in this.varHeaderDetect)
                            {
                                if (this.CompareFields(str2, str3))
                                {
                                    strArray3[num2] = "-found-";
                                }
                                num2++;
                            }
                        }
                        flag = true;
                        foreach (string str4 in strArray3)
                        {
                            if (str4 != "-found-")
                            {
                                flag = false;
                                break;
                            }
                        }
                        if (flag)
                        {
                            foreach (string str5 in this.varHeaderDetect)
                            {
                                column = this.Data.Columns.Add(str5, typeof(string));
                                int num5 = 0;
                                foreach (string str6 in strArray)
                                {
                                    if (this.CompareFields(str6, str5))
                                    {
                                        strArray2[num5] = str5;
                                    }
                                    num5++;
                                }
                            }
                        }
                    }
                    if ((((this.varDetectionLimit != 0) & (num3 > this.varDetectionLimit)) & !flag) & this.varDoDetect)
                    {
                        throw new dfNoHeaderException();
                    }
                    num3++;
                    if ((this.varRowLimit != 0) & (num3 > this.varRowLimit))
                    {
                        break;
                    }
                }
                if (this.varDoDetect & !flag)
                {
                    throw new dfNoHeaderException();
                }
            }
        }

        public void ReadXLS()
        {
            // Modifziert
            string[] strArray2 = new string[]{};
            Workbook workbook;
            Application application = new ApplicationClass();
            application.Visible = false;
            try
            {
                workbook = application.Workbooks.Open(this.varFileName, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value);
            }
            catch (Exception exception1)
            {
                ProjectData.SetProjectError(exception1);
                ProjectData.ClearProjectError();
                return;
            }
            Worksheet worksheet = (Worksheet) workbook.Worksheets[this.varXlsWorksheet];
            application.DisplayAlerts = false;
            application.EnableEvents = false;
            bool flag = false;
            string[] strArray = new string[this.varColLimit + 1];
            if (this.varDoDetect)
            {
                strArray2 = new string[(this.varHeaderDetect.Length - 1) + 1];
            }
            int num5 = this.XlsLastRow(ref worksheet, 50);
            for (int i = 1; i <= num5; i++)
            {
                DataColumn column;
                int num;
                if (!this.varDoDetect & !flag)
                {
                    int varColLimit = this.varColLimit;
                    for (int j = 1; j <= varColLimit; j++)
                    {
                        column = this.Data.Columns.Add(Conversions.ToString(j), typeof(string));
                        strArray[j] = Conversions.ToString(j);
                    }
                    flag = true;
                }
                if (flag)
                {
                    DataRow row = this.Data.NewRow();
                    int num7 = this.varColLimit;
                    num = 1;
                    while (num <= num7)
                    {
                        if (strArray[num] != null)
                        {
                            row[strArray[num]] = Conversions.ToString(((Range) worksheet.Cells[i, num]).get_Value(Missing.Value));
                        }
                        num++;
                    }
                    this.Data.Rows.Add(row);
                }
                if (this.varDoDetect & !flag)
                {
                    string str;
                    int num8 = this.varColLimit;
                    num = 1;
                    while (num <= num8)
                    {
                        str = Conversions.ToString(((Range) worksheet.Cells[i, num]).get_Value(Missing.Value));
                        if (str != null)
                        {
                            int index = 0;
                            foreach (string str2 in this.varHeaderDetect)
                            {
                                if (this.CompareFields(str, str2))
                                {
                                    strArray2[index] = "-found-";
                                }
                                index++;
                            }
                        }
                        num++;
                    }
                    flag = true;
                    foreach (string str3 in strArray2)
                    {
                        if (str3 != "-found-")
                        {
                            flag = false;
                            break;
                        }
                    }
                    if (flag)
                    {
                        foreach (string str4 in this.varHeaderDetect)
                        {
                            column = this.Data.Columns.Add(str4, typeof(string));
                            int num12 = this.varColLimit;
                            for (num = 1; num <= num12; num++)
                            {
                                str = Conversions.ToString(((Range) worksheet.Cells[i, num]).get_Value(Missing.Value));
                                if ((str != null) && this.CompareFields(str, str4))
                                {
                                    strArray[num] = str4;
                                }
                            }
                        }
                    }
                }
                if ((((this.varDetectionLimit != 0) & (i > this.varDetectionLimit)) & !flag) & this.varDoDetect)
                {
                    workbook.Saved = true;
                    workbook.Close(false, Missing.Value, Missing.Value);
                    application.Quit();
                    throw new dfNoHeaderException();
                }
                if ((this.varRowLimit != 0) & (i > this.varRowLimit))
                {
                    break;
                }
            }
            if (this.varDoDetect & !flag)
            {
                workbook.Saved = true;
                workbook.Close(false, Missing.Value, Missing.Value);
                application.Quit();
                throw new dfNoHeaderException();
            }
            workbook.Saved = true;
            workbook.Close(false, Missing.Value, Missing.Value);
            application.Quit();
        }

        private void StartTimer()
        {
            this.varStartDate = DateAndTime.Now;
        }

        private string StripChars(string txt, string StrippedChars)
        {
            foreach (char ch in StrippedChars.ToCharArray())
            {
                txt = txt.Replace(Conversions.ToString(ch), "");
            }
            return txt;
        }

        private int XlsLastRow(ref Worksheet Worksheet, int minSpaces)
        {
            IEnumerator enumerator = Worksheet.Rows.GetEnumerator();
            int num2 = 1;
            int num = 1;

            try
            {
                while (enumerator.MoveNext())
                {
                    Range current = (Range) enumerator.Current;
                    if (Conversions.ToString(((Range) current.Cells[1, 1]).get_Value(Missing.Value)) != null)
                    {
                        num2 = num;
                    }
                    num++;
                    if (num > (num2 + minSpaces))
                    {
                        return num2;
                    }
                }
            }
            finally
            {
                if (enumerator is IDisposable)
                {
                    (enumerator as IDisposable).Dispose();
                }
            }
            return num2;
        }

        public int ColLimit
        {
            get
            {
                return this.varColLimit;
            }
            set
            {
                if (value > 0x100)
                {
                    value = 0x100;
                }
                this.varColLimit = value;
            }
        }

        public string CsvDelimiter
        {
            get
            {
                return this.varCsvDelimiter;
            }
            set
            {
                this.varCsvDelimiter = value;
            }
        }

        public Encoding CsvEncoding
        {
            get
            {
                return this.varCsvEncoding;
            }
            set
            {
                this.varCsvEncoding = value;
            }
        }

        public int DetectionLimit
        {
            get
            {
                return this.varDetectionLimit;
            }
            set
            {
                this.varDetectionLimit = value;
            }
        }

        public bool DoHeaderDetect
        {
            get
            {
                return this.varDoDetect;
            }
            set
            {
                this.varDoDetect = value;
            }
        }

        public bool ExplicitDetect
        {
            get
            {
                return this.varExplicitDetect;
            }
            set
            {
                this.varExplicitDetect = value;
            }
        }

        public string FileName
        {
            get
            {
                return this.varFileName;
            }
            set
            {
                if (!File.Exists(value))
                {
                    throw new FileNotFoundException("Die Datei " + value + " exisitiert nicht.", value);
                }
                new FileIOPermission(FileIOPermissionAccess.Read, value).Demand();
                this.varFileName = value;
                this.varExtension = Path.GetExtension(value);
                this.GetTypeFromExtension();
            }
        }

        public dfFileType FileType
        {
            get
            {
                return this.varFileType;
            }
        }

        public string[] HeaderToDetect
        {
            get
            {
                return this.varHeaderDetect;
            }
            set
            {
                this.varHeaderDetect = value;
            }
        }

        public TimeSpan ReadingTime
        {
            get
            {
                return this.varReadingTime;
            }
        }

        public int RowLimit
        {
            get
            {
                return this.varRowLimit;
            }
            set
            {
                this.varRowLimit = value;
            }
        }

        public int XlsWorksheet
        {
            get
            {
                return this.varXlsWorksheet;
            }
            set
            {
                this.varXlsWorksheet = value;
            }
        }

        public enum dfFileType
        {
            CSV = 0,
            Unknown = -1,
            XLS = 1
        }
    }
}

